﻿using ControlzEx.Theming;
using LongSCADA_WPF.Helpers;
using LongSCADA_WPF.Models;
using LongSCADA_WPF.Services;
using LongSCADA_WPF.ViewModels;
using LongSCADA_WPF.Views;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Extensions.Logging;
using SqlSugar;
using System.Configuration;
using System.Data;
using System.Reflection;
using System.Windows;
using System.Windows.Media;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;

namespace LongSCADA_WPF
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public sealed partial class App : Application
    {
        //tookit and Di 注入---Ioc 控制反转 官网
        //  https://learn.microsoft.com/zh-cn/dotnet/communitytoolkit/mvvm/ioc
        public new static App Current => (App)Application.Current;

        public IServiceProvider Services { get;private set; }
        public App()
        {
            
            this.InitializeComponent();
            //初始化IoC
            Services = ConfigureService();
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            //切换主题颜色
            ThemeManager.Current.ChangeTheme(this, ThemeManager.Current.AddTheme(
                RuntimeThemeGenerator.Current.GenerateRuntimeTheme("Light",Colors.AliceBlue)));
            //显示 ShellView 窗体
            Services.GetService<ShellView>()?.Show();
        }
        // 依赖注入的服务都在这里进行注册
        private IServiceProvider? ConfigureService()
        {
            ServiceCollection services = new ServiceCollection();

            //配置类实现
            ConfigureJsonBybinder(services);

            //使用反射注册 Views and ViewModels
            RegisterViewsAndViewModels(services);

            /*//注册主窗体
            services.AddSingleton<ShellView>();
            services.AddSingleton<ShellViewModel>();

            //注册登录控件
            services.AddSingleton<LoginView>();
            services.AddSingleton<LoginViewModel>();

            //注册主窗体界面
            services.AddSingleton<MainView>();
            services.AddSingleton<MainViewModel>();

            //注册侧面菜单界面
            services.AddSingleton<IndexView>();
            services.AddSingleton<IndexViewModel>();
            services.AddSingleton<DeviceView>();
            services.AddSingleton<DeviceViewModel>();
            services.AddSingleton<UserView>();
            services.AddSingleton<UserViewModel>();
            */
            //注册需要的服务
            services.AddSingleton<UserModelService>();

            services.AddSingleton<GlobalHelper>();

            return services.BuildServiceProvider();
        }

        /// <summary>
        /// 将Json配置文件映射到实体类上
        /// </summary>
        private  void ConfigureJsonBybinder(ServiceCollection services)
        {
            // 注册工具类
            var cfgBuilder = new ConfigurationBuilder()
                    .SetBasePath(Environment.CurrentDirectory + "\\Configs")
                    .AddJsonFile("appsettings.json", false, true);
            //构建json配置
            IConfiguration configuration = cfgBuilder.Build();

            #region 实现单例注入日志配置
            //实现单例注入日志配置   注入 ILogger<T>
            services.AddSingleton<IConfiguration>(configuration)
                .AddLogging(log =>
                {
                    log.ClearProviders();
                    log.SetMinimumLevel(LogLevel.Trace);
                    log.AddNLog();
                });
            //获取日志参数
            IConfigurationSection nLogConfig = configuration.GetSection("NLog");
            LogManager.Configuration = new NLogLoggingConfiguration(nLogConfig);
            #endregion

            #region 实现单例注入SqlSugar配置
            //改造 SqlSugarHelper，枚举尝试转换
            bool paresResurt = Enum.TryParse<SqlSugar.DbType>(configuration["SqlParam:DbType"],out SqlSugar.DbType dbType);
            string connectionString = configuration["SqlParam:ConnectionString"];

            if (paresResurt)
            {
                SqlSugarHelper.AddSqlSugarSetup(dbType, connectionString);
            }
            #endregion

            //参数配置及映射  注入IOptionsSnapshot<RootParam>.Value
            services.AddOptions()
                .Configure<RootParam>(e => configuration.Bind(e))
                .Configure<SqlParam>(e => configuration.GetSection("SqlParam").Bind(e))
                .Configure<SystemParam>(e => configuration.GetSection("SystemParam").Bind(e))
                .Configure<PlcParam>(e => configuration.GetSection("PlcParam").Bind(e));
        }

        /// <summary>
        /// 注册 **View and **ViewModel；文件名不可更改
        /// </summary>
        /// <param name="services"></param>
        private void RegisterViewsAndViewModels(ServiceCollection services)
        {
            Assembly assembly = typeof(App).Assembly;
            List<Type> viewTypes = assembly.GetTypes().Where(t => t.Name.EndsWith("View")&&!t.IsAbstract)
                .ToList();
            foreach (var viewType in viewTypes)
            {
                //注册 ***View
                services.AddSingleton(viewType);

                //注册 ***ViewModel
                var viewModelType = viewType.Assembly.GetType(viewType.Namespace.Replace("Views", "ViewModels") + "." + viewType.Name.Replace("View", "ViewModel"));
                if (viewModelType != null)
                {
                    services.AddSingleton(viewModelType);
                }
            }
        }
    }

}
